#include <iostream>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#define PAGE_SIZE 4096
//命令行参数中输入文件名，通过mmap对文件内容进行操作
int main(int argc , char* argv[])
{
    if(argc != 2)
    {
        std::cout << "Usage: " << argv[0] << " filename" << std::endl;
        return 1;
    }
    //1.打开目标文件.mmap需要你自己先打开文件
    int fd = ::open(argv[1] , O_RDWR | O_CREAT | O_TRUNC , 0666);
    if(fd < 0)
    {
        std::cerr << "open file error!" << std::endl;
        return 2;
    }
    //2.手动调整文件的大小为PAGE_SIZE,方便我们进行合法映射
        //ftruncate
        if(::ftruncate(fd,PAGE_SIZE) < 0)
        {
            std::cerr << "Failed to ftruncate file !" << std::endl;
            return 3;
        }
    //3. 文件映射
    char* shmaddr = (char*)::mmap(nullptr , PAGE_SIZE , PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0);
    //addr : 映射的起始地址
    //length : 映射区域的长度
    //prot : 内存保护权限
    //flags : 映射类型和选项
    //offset : 文件偏移量
    //映射失败，返回MAP_FAILED
    if(shmaddr == MAP_FAILED)
    {
        std::cerr << "Failed to mmap file" << std::endl;
        return 4;
    }
    //4.进行文件操作
    for(char c = 'a' ; c <= 'z' ; ++c)
    {
        *(shmaddr + c - 'a') = c;
        sleep(1);
    }
    //5.关闭映射
    if(::munmap(shmaddr,PAGE_SIZE) < 0)
    {
        std::cerr << "Failed to munmap file" << std::endl;
        return 5;
    }
    //关闭文件
    close(fd);
    return 0;
}